home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1995 #5 & #6
/
Amiga Plus CD - 1995 - No. 5 and 6.iso
/
pd
/
netz
/
term
/
extras
/
source
/
gtlayout-source.lha
/
LT_Build.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-03
|
16KB
|
745 lines
/* GadTools layout toolkit
**
** Copyright © 1993-1995 by Olaf `Olsen' Barthel
** Freely distributable.
*/
#include "gtlayout_global.h"
struct Window * __stdargs
LT_Build(LayoutHandle *Handle,...)
{
struct Window *Result;
va_list VarArgs;
va_start(VarArgs,Handle);
Result = LT_BuildA(Handle,(struct TagItem *)VarArgs);
va_end(VarArgs);
return(Result);
}
/*****************************************************************************/
struct Window * LIBENT
LT_BuildA(REG(a0) LayoutHandle *handle,REG(a1) struct TagItem *TagParams)
{
LONG left, top, width, height;
struct IBox newBounds;
struct Menu *menu = NULL;
struct TagItem *item;
LONG placeLeft;
LONG placeTop;
struct IBox zoomBox;
struct IBox *zoom;
LONG i;
struct TextFont *font;
struct TagItem *NewTags = NULL,*Tags;
BOOL BlockParent = handle -> BlockParent,
SmartZoom = FALSE;
BOOL MakeVisible = FALSE;
struct Window *Parent = handle -> Parent;
STRPTR title = NULL;
struct IBox *bounds = NULL;
LONG extraWidth = 0,
extraHeight = 0;
ULONG IDCMP = NULL;
UWORD align = 0;
WORD MinX,
MinY,
MaxX,
MaxY;
BOOL SizeGadget = FALSE,
SizeBRight = FALSE,
SizeBBottom = FALSE;
ULONG BorderBottom,
BorderRight;
struct Menu *LocalMenu = NULL;
struct TagItem *LocalMenuTags = NULL;
struct NewMenu *LocalMenuTemplate = NULL;
if(!handle)
return(NULL);
/* ALWAYS */
{
struct TagItem *TagList = (struct TagItem *)TagParams;
while(item = NextTagItem(&TagList))
{
switch((ULONG)item -> ti_Tag)
{
case LAWN_MenuTemplate:
LocalMenuTemplate = (struct NewMenu *)item -> ti_Data;
break;
case LAWN_MenuTags:
LocalMenuTags = (struct TagItem *)item -> ti_Data;
break;
case LAWN_FlushLeft:
handle -> FlushLeft = item -> ti_Data;
break;
case LAWN_FlushTop:
handle -> FlushTop = item -> ti_Data;
break;
case LAWN_TitleText:
title = (STRPTR)item -> ti_Data;
break;
case LAWN_TitleID:
if(!handle -> LocaleHook)
return(NULL);
else
title = (STRPTR)CallHookPkt(handle -> LocaleHook,handle,(APTR)item -> ti_Data);
break;
case LAWN_Bounds:
bounds = (struct IBox *)item -> ti_Data;
break;
case LAWN_ExtraWidth:
extraWidth = item -> ti_Data;
break;
case LAWN_ExtraHeight:
extraHeight = item -> ti_Data;
break;
case LAWN_IDCMP:
IDCMP = item -> ti_Data;
break;
case LAWN_AlignWindow:
align = item -> ti_Data;
break;
}
}
}
#ifdef DO_MENUS
if(LocalMenuTags)
{
if(LocalMenu = LT_NewMenuTags(LAMN_Handle,handle,TAG_MORE,LocalMenuTags))
{
menu = LocalMenu;
handle -> IDCMP |= IDCMP_MENUPICK;
}
else
return(NULL);
}
else
{
if(LocalMenuTemplate)
{
if(LocalMenu = LT_NewMenuTemplate(handle -> Screen,handle -> TextAttr,handle -> AmigaGlyph,handle -> CheckGlyph,NULL,LocalMenuTemplate))
{
menu = LocalMenu;
handle -> IDCMP |= IDCMP_MENUPICK;
}
else
return(NULL);
}
}
#endif // DO_MENUS
if(!bounds)
{
LTP_GetDisplayClip(handle -> Screen,&newBounds . Left,&newBounds . Top,&newBounds . Width,&newBounds . Height);
bounds = &newBounds;
}
left = handle -> Screen -> WBorLeft;
if(title)
top = handle -> Screen -> WBorTop + handle -> Screen -> Font -> ta_YSize + 1;
else
top = handle -> Screen -> WBorTop;
BorderRight = handle -> Screen -> WBorRight;
BorderBottom = handle -> Screen -> WBorBottom;
if(handle -> ResizeView)
{
if(handle -> ResizeView -> Special . List . ResizeY)
BorderBottom = LTP_GetSizeHeight(handle);
else
{
if(handle -> ResizeView -> Special . List . ResizeX)
BorderRight = LTP_GetSizeWidth(handle);
}
}
if(!handle -> FlushLeft)
{
left += handle -> InterWidth;
BorderRight += handle -> InterWidth;
}
if(!handle -> FlushTop)
{
top += handle -> InterHeight;
BorderBottom += handle -> InterHeight;
}
LTP_CreateGadgets(handle,bounds,left,top,left + BorderRight,top + BorderBottom);
if(handle -> Failed)
return(NULL);
width = left + handle -> TopGroup -> Width + BorderRight;
height = top + handle -> TopGroup -> Height + BorderBottom;
if(handle -> ResizeView)
{
WORD GlyphWidth,GlyphHeight;
MaxX = MinX = width;
MaxY = MinY = height;
if(handle -> ResizeView -> Special . List . ResizeX)
MaxX = handle -> Screen -> Width;
if(handle -> ResizeView -> Special . List . ResizeY)
{
MaxY = handle -> Screen -> Height;
SizeBBottom = TRUE;
}
else
SizeBRight = TRUE;
SizeGadget = TRUE;
if(handle -> ResizeView -> Special . List . TextAttr)
{
GlyphWidth = handle -> ResizeView -> Special . List . FixedGlyphWidth;
GlyphHeight = handle -> ResizeView -> Special . List . FixedGlyphHeight;
}
else
{
GlyphWidth = handle -> GlyphWidth;
GlyphHeight = handle -> RPort . TxHeight;
}
if(handle -> ResizeView -> Special . List . MinChars && handle -> ResizeView -> Special . List . MinChars < handle -> ResizeView -> Chars)
MinX -= GlyphWidth * (handle -> ResizeView -> Chars - handle -> ResizeView -> Special . List . MinChars);
if(handle -> ResizeView -> Special . List . MinLines && handle -> ResizeView -> Special . List . MinChars < handle -> ResizeView -> Lines)
MinY -= GlyphHeight * (handle -> ResizeView -> Lines - handle -> ResizeView -> Special . List . MinLines);
}
else
{
MaxX = MinX = width;
MaxY = MinY = height;
}
if(align & ALIGNF_LEFT)
placeLeft = 0;
else
{
if(align & ALIGNF_RIGHT)
placeLeft = bounds -> Width - (width + extraWidth);
else
placeLeft = (bounds -> Width - (width + extraWidth)) / 2;
}
if(align & ALIGNF_TOP)
placeTop = 0;
else
{
if(align & ALIGNF_BOTTOM)
placeTop = bounds -> Height - (height + extraHeight);
else
placeTop = (bounds -> Height - (height + extraHeight)) / 2;
}
if(align & ALIGNF_EXTRA_LEFT)
placeLeft += extraWidth;
else
{
if(!(align & ALIGNF_EXTRA_RIGHT))
placeLeft += extraWidth / 2;
}
if(align & ALIGNF_EXTRA_TOP)
placeTop += extraHeight;
else
{
if(!(align & ALIGNF_EXTRA_BOTTOM))
placeTop += extraHeight / 2;
}
placeLeft += bounds -> Left;
placeTop += bounds -> Top;
if(placeLeft < 0)
placeLeft = 0;
if(placeTop < 0)
placeTop = 0;
zoom = NULL;
handle -> AutoRefresh = TRUE;
#ifdef DO_CLONING
if(handle -> CloneExtra)
{
placeLeft = 0;
placeTop = handle -> CloneExtra -> Screen -> BarHeight + 1;
zoomBox . Left = placeLeft;
zoomBox . Top = placeTop;
}
#endif /* DO_CLONING */
/* ALWAYS */
{
struct TagItem *TagList = (struct TagItem *)TagParams;
while(item = NextTagItem(&TagList))
{
switch((ULONG)item -> ti_Tag)
{
case LA_Menu:
if(!menu)
{
handle -> IDCMP |= IDCMP_MENUPICK;
menu = (struct Menu *)item -> ti_Data;
}
break;
case LAWN_SmartZoom:
SmartZoom = item -> ti_Data;
if(!SmartZoom)
break;
case LAWN_Zoom:
if(item -> ti_Data)
{
if(title && SmartZoom)
{
STATIC UWORD WhichTable[3] =
{
CLOSEIMAGE,
ZOOMIMAGE,
DEPTHIMAGE
};
LONG Size = 0,i;
BOOLEAN GotIt = TRUE;
UWORD SizeType;
Object *Image;
if(handle -> Screen -> Flags & SCREENHIRES)
SizeType = SYSISIZE_MEDRES;
else
SizeType = SYSISIZE_LOWRES;
for(i = 0 ; i < 3 ; i++)
{
if(Image = NewObject(NULL,SYSICLASS,
SYSIA_Size, SizeType,
SYSIA_Which, WhichTable[i],
SYSIA_DrawInfo, handle -> DrawInfo,
TAG_DONE))
{
ULONG Width;
GetAttr(IA_Width,Image,&Width);
Size += Width;
DisposeObject(Image);
}
else
GotIt = FALSE;
}
if(GotIt)
{
Size += 8 + TextLength(&handle -> Screen -> RastPort,title,strlen(title)) + 8;
zoomBox . Width = Size;
}
else
zoomBox . Width = width;
}
else
zoomBox . Width = width;
if(V39)
{
zoomBox . Left = -1;
zoomBox . Top = -1;
}
else
{
zoomBox . Left = placeLeft;
zoomBox . Top = placeTop;
}
zoomBox . Height = handle -> Screen -> WBorTop + handle -> Screen -> Font -> ta_YSize + 1;
zoom = &zoomBox;
}
break;
case LAWN_UserPort:
handle -> MsgPort = (struct MsgPort *)item -> ti_Data;
break;
case LAWN_HelpHook:
handle -> HelpHook = (struct Hook *)item -> ti_Data;
break;
case LAWN_Left:
placeLeft = item -> ti_Data;
break;
case LAWN_Top:
placeTop = item -> ti_Data;
break;
case LAWN_Parent:
Parent = (struct Window *)item -> ti_Data;
break;
case LAWN_BlockParent:
BlockParent = item -> ti_Data;
break;
case LAWN_BelowMouse:
if((placeLeft = handle -> Screen -> MouseX - (width / 2)) < 0)
placeLeft = 0;
if((placeTop = handle -> Screen -> MouseY - (height / 2)) < 0)
placeTop = 0;
break;
case LAWN_MaxPen:
handle -> MaxPen = (LONG)item -> ti_Data;
break;
case LAWN_MoveToWindow:
handle -> MoveToWindow = (LONG)item -> ti_Data;
break;
case LAWN_AutoRefresh:
handle -> AutoRefresh = (LONG)item -> ti_Data;
break;
case LAWN_Show:
MakeVisible = item -> ti_Data;
break;
}
}
}
Tags = (struct TagItem *)TagParams;
if(handle -> BackgroundPen && !V39)
{
if(NewTags = CloneTagItems(Tags))
{
STATIC Tag Filter[] = { WA_SimpleRefresh,TAG_DONE };
FilterTagItems(NewTags,Filter,TAGFILTER_NOT);
Tags = NewTags;
}
else
{
#ifdef DO_MENUS
LT_DisposeMenu(LocalMenu);
#endif // DO_MENUS
return(NULL);
}
}
if(Parent)
{
WORD Left,Top,Width,Height,MoveLeft,MoveTop,
WindowLeft,WindowTop,WindowWidth,WindowHeight;
WindowLeft = Parent -> LeftEdge + Parent -> BorderLeft;
WindowTop = Parent -> TopEdge + Parent -> BorderTop;
WindowWidth = Parent -> Width - (Parent -> BorderLeft + Parent -> BorderRight);
WindowHeight = Parent -> Height - (Parent -> BorderTop + Parent -> BorderBottom);
LTP_GetDisplayClip(Parent -> WScreen,&Left,&Top,&Width,&Height);
if((MoveLeft = WindowLeft + (WindowWidth - width) / 2) < 0)
MoveLeft = 0;
if((MoveTop = WindowTop + (WindowHeight - height) / 2) < 0)
MoveTop = 0;
if(MoveLeft < Left || MoveLeft + width > Left + Width)
MoveLeft = -1;
if(MoveTop < Top || MoveTop + height > Top + Height)
MoveTop = -1;
if(MoveTop != -1 && MoveLeft != -1)
{
placeLeft = MoveLeft;
placeTop = MoveTop;
}
}
if(BlockParent && Parent)
{
LT_LockWindow(Parent);
handle -> Parent = Parent;
}
if(SizeGadget)
zoom = NULL;
if(handle -> Window = OpenWindowTags(NULL,
WA_Left, placeLeft,
WA_Top, placeTop,
WA_Width, width,
WA_Height, height,
WA_NewLookMenus, TRUE,
WA_CustomScreen, handle -> Screen,
WA_BackFill, &handle -> BackfillHook,
WA_MinWidth, MinX,
WA_MinHeight, MinY,
WA_MaxWidth, MaxX,
WA_MaxHeight, MaxY,
WA_SizeGadget, SizeGadget,
WA_SizeBBottom, SizeBBottom,
WA_SizeBRight, SizeBRight,
WA_PointerDelay, TRUE,
WA_BusyPointer, TRUE,
zoom ? WA_Zoom : TAG_IGNORE, zoom,
!handle -> MsgPort ? WA_IDCMP : TAG_IGNORE, IDCMP_REFRESHWINDOW | IDCMP_RAWKEY | IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_MOUSEBUTTONS | IDCMP_CHANGEWINDOW | IDCMP | handle -> IDCMP,
title ? WA_Title : TAG_IGNORE, title,
handle -> AmigaGlyph ? WA_AmigaKey : TAG_IGNORE, handle -> AmigaGlyph,
handle -> CheckGlyph ? WA_Checkmark : TAG_IGNORE, handle -> CheckGlyph,
TAG_MORE,Tags))
{
font = handle -> RPort . Font;
handle -> RPort = *handle -> Window -> RPort;
LTP_SetFont(handle,font);
#ifdef DO_BOOPSI_KIND
if(handle -> BOOPSIList)
{
AddGList(handle -> Window,(struct Gadget *)handle -> BOOPSIList,(UWORD)-1,(UWORD)-1,NULL);
RefreshGList((struct Gadget *)handle -> BOOPSIList,handle -> Window,NULL,(UWORD)-1);
}
#endif /* DO_BOOPSI_KIND */
AddGList(handle -> Window,handle -> List,(UWORD)-1,(UWORD)-1,NULL);
RefreshGList(handle -> List,handle -> Window,NULL,(UWORD)-1);
if(NewTags)
{
FreeTagItems(NewTags);
NewTags = NULL;
}
if(V39)
{
if(handle -> MaxPen > 0)
{
SetMaxPen(&handle -> RPort,handle -> MaxPen);
SetMaxPen(handle -> Window -> RPort,handle -> MaxPen);
}
}
GT_RefreshWindow(handle -> Window,NULL);
LTP_DrawGroup(handle,handle -> TopGroup);
LTP_MoveToWindow(handle);
handle -> Window -> UserData = (APTR)handle;
if(handle -> MsgPort)
{
handle -> Window -> UserPort = handle -> MsgPort;
if(!ModifyIDCMP(handle -> Window,IDCMP_CHANGEWINDOW | IDCMP_REFRESHWINDOW | IDCMP_RAWKEY | IDCMP_INACTIVEWINDOW | IDCMP_ACTIVEWINDOW | IDCMP_MOUSEBUTTONS | IDCMP | handle -> IDCMP))
{
handle -> Window -> UserPort = NULL;
return (NULL);
}
}
if(menu)
SetMenuStrip(handle -> Window,menu);
handle -> Menu = LocalMenu;
handle -> Previous = NULL;
for(i = 0 ; i < handle -> Count ; i++)
{
if(handle -> GadgetArray[i])
{
ObjectNode *node;
if(GETOBJECT(handle -> GadgetArray[i],node))
{
if(LIKE_STRING_KIND(node) || (node -> Type == INTEGER_KIND))
{
if(!handle -> Previous)
handle -> Previous = handle -> GadgetArray[i];
}
}
}
}
#ifdef DO_CLONING
if(handle -> CloneExtra)
ScreenToFront(handle -> Window -> WScreen);
#endif
if(V39)
SetWindowPointerA(handle -> Window,NULL);
if(MakeVisible)
{
ScreenToFront(handle -> Screen);
if(V39)
{
WORD left,top,width,height;
LTP_GetDisplayClip(handle->Screen,&left,&top,&width,&height);
if(handle -> Window -> Width < width)
left = (width - handle -> Window -> Width) / 2;
else
left = 0;
if(handle -> Window -> Height < height)
top = (height - handle -> Window -> Height) / 2;
else
top = 0;
if((left = handle -> Window -> LeftEdge - left) < 0)
left = 0;
if((top = handle -> Window -> TopEdge - top) < 0)
top = 0;
ScreenPosition(handle -> Screen,SPOS_MAKEVISIBLE,left,top,left + width - 1,top + height - 1);
}
}
}
else
{
if(handle -> Parent)
{
LT_UnlockWindow(handle -> Parent);
handle -> Parent = NULL;
}
#ifdef DO_MENUS
LT_DisposeMenu(LocalMenu);
#endif // DO_MENUS
}
FreeTagItems(NewTags);
return(handle -> Window);
}
/*****************************************************************************/
struct Window * __stdargs
LT_Layout(LayoutHandle *handle, STRPTR title,struct IBox *bounds,LONG extraWidth, LONG extraHeight,ULONG IDCMP, UBYTE align, ...)
{
struct Window *Result;
va_list VarArgs;
va_start(VarArgs,align);
Result = LT_Build(handle,
LAWN_Title, title,
LAWN_Bounds, bounds,
LAWN_ExtraWidth, extraWidth,
LAWN_ExtraHeight, extraHeight,
LAWN_IDCMP, IDCMP,
LAWN_AlignWindow, align,
TAG_MORE,(struct TagItem *)VarArgs);
va_end(VarArgs);
return(Result);
}
/*****************************************************************************/
struct Window * LIBENT
LT_LayoutA(REG(a0) LayoutHandle *handle, REG(a1) STRPTR title,REG(a2) struct IBox *bounds,REG(d0) LONG extraWidth, REG(d1) LONG extraHeight,REG(d2) ULONG IDCMP, REG(d3) UBYTE align, REG(a3) struct TagItem *TagParams)
{
struct Window *Result;
Result = LT_Build(handle,
LAWN_Title, title,
LAWN_Bounds, bounds,
LAWN_ExtraWidth, extraWidth,
LAWN_ExtraHeight, extraHeight,
LAWN_IDCMP, IDCMP,
LAWN_AlignWindow, align,
TAG_MORE,TagParams);
return(Result);
}